#include "DOSensor.h"
#define DevAddr 0x03 //设备ID,应设置为
static unsigned char _SendData[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char _RecvData_DO_PH_Temp[21] = {0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x00, 0x00,
                                    0x00, 0x00};

bool DOSensor::checkDevID(void)
{
    unsigned short acq_DevID_REG = DOSensor::DevID_REG;
    _SendData[0] = (DevID & 0xFF);//设备地址
    _SendData[1] = (DOSensor::ReadFuncCode & 0xFF); //读取
    _SendData[2] = ((acq_DevID_REG>>8) & 0xFF);//待读取的起始地址高八位
    _SendData[3] = (acq_DevID_REG & 0xFF);//待读取的起始地址高八位
    _SendData[4] = (0x00); //读取的数量
    _SendData[5] = 0x02; //读取的数量低八位
    // _SendData[6] = 0xE5;
    // _SendData[7] = 0xEB;
    uint16_t crc = this->modbus->CRC16_MudBus(_SendData, 6);//进行CRC校验
    _SendData[6] = (crc & 0xFF);//CRC的低八位
    _SendData[7] = ((crc>>8) & 0xFF);//CRC的高八位
    // Serial.print("crc Val is:  ");
    // Serial.println(crc,HEX);
    this->modbus->SendData(_SendData, 8);//发送数据
    delay(100);//等待100ms返回数据

    bool ret = this->modbus->RecvData(_RecvData_DO_PH_Temp, 9);//接收数据
    if (ret == false)
    {
        Serial.println("DO sensor Data is no response!");
        return false;
    }
    uint16_t crc_Recv = this->modbus->CRC16_MudBus(_RecvData_DO_PH_Temp, 7);//进行CRC校验
    if (((crc_Recv>>8) & 0xFF) != _RecvData_DO_PH_Temp[8] || (crc_Recv & 0xFF) != _RecvData_DO_PH_Temp[7])//校验成功
    {
        Serial.println("DO sensor Data CRC check is wrong in checkDevID!");
        return false;
    }
    unsigned char devID_Ret = _RecvData_DO_PH_Temp[4];
    if ((devID_Ret & 0xFF) == DevAddr)
        return true;
    else return false;
}


bool DOSensor::initDOSensor(Modbus_RTU * _modbus)
{
    DevID = DevAddr & 0xFF;//设备ID
    modbus = _modbus;
    return checkDevID();
}

bool DOSensor::ReadDO_PH_Temp_Data(void)
{
    unsigned short func = 0x0010;
    _SendData[0] = (DevID & 0xFF);//设备地址
    _SendData[1] = (DOSensor::ReadFuncCode & 0xFF); //读取
    _SendData[2] = ((func>>8) & 0xFF);//待读取的起始地址高八位
    _SendData[3] = (func & 0xFF);//待读取的起始地址高八位
    _SendData[4] = (0x00); //读取的数量
    _SendData[5] = 0x08; //读取的数量低八位
    uint16_t crc = this->modbus->CRC16_MudBus(_SendData, 6);//进行CRC校验
    _SendData[6] = (crc & 0xFF);//CRC的低八位
    _SendData[7] = ((crc>>8) & 0xFF);//CRC的高八位
    this->modbus->SendData(_SendData, 8);//发送数据
    delay(200);//等待100ms返回数据

    bool ret = this->modbus->RecvData(_RecvData_DO_PH_Temp, 21);//接收数据
    if (ret == false)
    {
        return false;
    }
    uint16_t crc_Recv = this->modbus->CRC16_MudBus(_RecvData_DO_PH_Temp, 19);//进行CRC校验
    if (((crc_Recv>>8) & 0xFF) != _RecvData_DO_PH_Temp[20] || (crc_Recv & 0xFF) != _RecvData_DO_PH_Temp[19])//校验成功
    {
        Serial.println("ReadFun : TEMP DO CRC Check failed!!!");
        return false;
    }
    this->tempValue = (short) ((_RecvData_DO_PH_Temp[5]<<8) | _RecvData_DO_PH_Temp[6]);
    this->DOPercent = (unsigned short) ((_RecvData_DO_PH_Temp[7]<<8) | _RecvData_DO_PH_Temp[8]);
    this->DOValue = (unsigned short) ((_RecvData_DO_PH_Temp[11]<<8) | _RecvData_DO_PH_Temp[12]);
    this->StatusREG = (unsigned int) ((_RecvData_DO_PH_Temp[15]<<24) | (_RecvData_DO_PH_Temp[16]<<16) | (_RecvData_DO_PH_Temp[17]<<8) | _RecvData_DO_PH_Temp[18]);

    unsigned short phREG = 0x0026;
    _SendData[0] = (DevID & 0xFF);//设备地址
    _SendData[1] = (DOSensor::ReadFuncCode & 0xFF); //读取
    _SendData[2] = ((phREG >> 8) & 0xFF);//待读取的起始地址高八位
    _SendData[3] = (phREG & 0xFF);//待读取的起始地址高八位
    _SendData[4] = (0x00); //读取的数量
    _SendData[5] = 0x02; //读取的数量低八位
    crc = this->modbus->CRC16_MudBus(_SendData, 6);//进行CRC校验
    _SendData[6] = (crc & 0xFF);//CRC的低八位
    _SendData[7] = ((crc>>8) & 0xFF);//CRC的高八位
    this->modbus->SendData(_SendData, 8);//发送数据

    delay(200);//等待100ms返回数据
    ret = this->modbus->RecvData(_RecvData_DO_PH_Temp, 9);//接收数据
    crc_Recv = this->modbus->CRC16_MudBus(_RecvData_DO_PH_Temp, 7);//进行CRC校验
    if (((crc_Recv>>8) & 0xFF) != _RecvData_DO_PH_Temp[8] || (crc_Recv & 0xFF) != _RecvData_DO_PH_Temp[7])//校验成功
    {
        Serial.println("ReadFun : PH CRC Check failed!!!");
        return false;
    }

    this->PHValue = (unsigned short) ((_RecvData_DO_PH_Temp[3]<<8) | _RecvData_DO_PH_Temp[4]);
    return true;
};


float DOSensor::GetPH(void)
{
    return PHValue / 1000.0;
}

float DOSensor::GetTemperature(void)
{
    return tempValue / 100.0;
}

float DOSensor::GetDOPercent(void)
{
    return DOPercent / 100.0;
}

float DOSensor::GetDOValue(void)
{
    return DOValue / 100.0;
}

bool DOSensor::SetFunc(DOSensor::FuncCode func, short SetData)
{
    _SendData[0] = (DevID & 0xFF);//设备地址
    _SendData[1] = (DOSensor::SetFuncCOde & 0xFF); //读取
    _SendData[2] = ((func>>8) & 0xFF);//待读取的起始地址高八位
    _SendData[3] = (func & 0xFF);
    _SendData[4] = ((SetData>>8) & 0xFF);
    _SendData[5] = (SetData & 0xFF);
    uint16_t crc = this->modbus->CRC16_MudBus(_SendData, 6);//进行CRC校验
    _SendData[6] = (crc & 0xFF);//CRC的低八位
    _SendData[7] = ((crc>>8) & 0xFF);//CRC的高八位
    this->modbus->SendData(_SendData, 8);//发送数据
    delay(100);//等待100ms返回数据
    bool ret = this->modbus->RecvData(_SendData, 8);//接收数据
    if (ret == false)
    {
        return false;
    }
    uint16_t crc_Recv = this->modbus->CRC16_MudBus(_SendData, 6);//进行CRC校验
    if (((crc_Recv>>8) & 0xFF) != _SendData[7] || (crc_Recv & 0xFF) != _SendData[6])//校验失败
    {
        Serial.println("SetFunc : RecvData CRC Check failed!!!");
        return false;
    }
    return true;
}